import { __DEV__ } from '@/app.config';
import layoutStore from '@/store/index'
import { FormInstance, FormItemProp } from 'element-plus';
import { ref, watch } from 'vue'
import { useI18n } from 'vue-i18n';
/*
 * @param params useValidForm 传参，可以通过解构获取对应参数
 * @returns 可以返回一些公共的校验方法
 */
export const useValidForm = (params: any = {}) => {
    const layout = layoutStore()
    // 用于收集校验错误的字段
    const errroFieldList = ref<any>(new Map())
    const formRef = ref<FormInstance>()
    const i18n = useI18n()
    const getType = (data: any) => Object.prototype.toString.call(data)

    watch(() => layout.getLanguage, (n, o) => {
        if (getType(formRef.value) === "[object Array]") {
            if (errroFieldList.value) {
                for (const [key, value] of errroFieldList.value) {
                    if (value) {
                        const propsList = Array.from(value)
                        // 先清空再重新触发校验是因为第一个 el-form-item 重新触发校验时 message 的数据是对的但是页面上的 error message 不会重新更新，其它项不会这样，但是暂时找不到原因
                        formRef.value?.[key].clearValidate(propsList)
                        requestAnimationFrame(() => {
                            formRef.value?.[key].validateField(propsList)
                        })
                    }
                }
            }
        } else {
            const propsList: any = Array.from(errroFieldList.value.get(-1) ?? new Set())
            if (propsList?.length > 0) {
                formRef.value?.clearValidate(propsList)
                requestAnimationFrame(() => {
                    formRef.value?.validateField(propsList)
                })
            }
        }
    })

    /**
     * 收集校验错误的字段
     * 
     * @param prop 校验项的名称
     * @param isValid 是否校验通过
     * @param message 校验信息
     * @param formRefIndex 用于判断当前校验的是第几个表单项，如果没有对 el-form 进行循环（没有传值），则默认为 -1
     */
    const triggerValidate = (prop: FormItemProp, isValid: boolean, message: string, formRefIndex: number = -1) => {
        // formRefIndex 值大于 -1 针对的是 el-form 绑定的值为动态数组的情况
        const _errroFieldList = errroFieldList.value.get(formRefIndex) ?? new Set()
        // 如果校验不通过，则将其存入 errroFieldList 中, 否则将其从 errroFieldList 中删除
        if (!isValid) {
            _errroFieldList.add(prop)
        } else {
            _errroFieldList.delete(prop)
        }
        if (_errroFieldList.size <= 0) {
            errroFieldList.value.delete(formRefIndex)
        } else {
            errroFieldList.value.set(formRefIndex, _errroFieldList)
        }
    }

    return {
        errroFieldList,
        formRef,
        i18n,
        triggerValidate,
    }
}